/*! JRoll.Infinite v1.0.4 ~ (c) 2015
 *Author:jlong
 *Email:jlong@chjtx.com
 *Website:http://www.chjtx.com/JRoll/#todo/tutorial?do=infinite
 */
;(function(window, document) {
	"use strict";
	var sty = document.createElement('div').style;
	var tSF = ("transform" in sty) ? "transform" : "-webkit-transform";
	var tSD = ("transitionDuration" in sty) ? "transition-duration" : "-webkit-transition-duration";
	var normalImport = function(d){ //强制普通模式引入，script添加"jroll-import='normal'"属性后将忽略exports/define等方式引入
		var s = d.getElementsByTagName("script");
		for (var i=s.length-1; i>-1; i--) {
			if (s[i].getAttribute("jroll-import") === 'normal') {
				return true;
			}
		}
		return false;
	}(document);

	function gId(id) {
		return document.getElementById(id);
	}
	function qSr(selector) {
		return document.querySelector(selector);
	}
	function cDiv(tag) {
		return document.createElement(tag);
	}
	function randomIdPrefix() { //得到一个随机id前缀，为避免多次使用JRoll_Infinite产生相同的ID造成冲突
		var a = ["a","b","c","d","e","f","g","h","i","j"];
		var r = "", i=5;
		while (i--) {
			r += a[parseInt(Math.random()*10, 10)];
		}
		return r + "_";
	}
	function compile(text) {
		var t = text;
		var s = "'use strict';\nvar __t='';__t+='";
		var i = 0;
		var r = /\{\{=([^\{]+)\}\}|\{\{(each [\w\$\._]+ as [\w\$_]+ [\w\$_]+)\}\}|\{\{if ([^\{]+)\}\}|\{\{(else)\}\}|\{\{else if ([^\{]+)\}\}|(\{\{\/each\}\}|\{\{\/if\}\})|\{\{([^\{]+)\}\}/g;
		//预处理，去除多余空格、回车、转换单引号
		t = t.replace(/(\n|\r)|(\{\{\s+)|(\s+\}\})|(\s{2,})|(')/g, function(match, enter, left, right, space, quote) {
			var temp;
			if (enter) {
				temp = "";
			} else if (left) {
				temp = "{{";
			} else if (right) {
				temp = "}}";
			} else if (space) {
				temp = " ";
			} else if (quote) {
				temp = "\\\'";
			}
			return temp;
		});
		//替换字符串
		t.replace(r, function(match, _value, _each, _if, _else, _elseif, _close, _other, offset){
			s += t.slice(i, offset);
			i = offset + match.length;

			if (_value) {
				s += "'+("+_value+")+'";
			} else if (_each) {
				var p = _each.split(" ");
				s += "';\nfor(var "+p[4]+"=0,"+p[3]+";"+p[4]+"<"+p[1]+".length;"+p[4]+"++){\n"+p[3]+"="+p[1]+"["+p[4]+"];\n__t+='";
			} else if (_if) {
				s += "';\nif("+_if+"){\n__t+='";
			} else if (_else) {
				s += "';\n}else{\n__t+='";
			} else if (_elseif) {
				s += "';\n}else if("+_elseif+"){\n__t+='";
			} else if (_close) {
				s += "';\n};\n__t+='";
			} else if (_other) {
				s += "';\n"+_other+";\n__t+='";
			}
			return match;
		});
		s += t.slice(i) + "\';return __t;";

		return new Function("_obj", s);
	}
	function render(compiled, data) {
		return compiled(data);
	}
	//在head插入动画css
	(function(document){
		if (!gId("jroll_infinite_style")) {
			var style = cDiv("style");
			style.id = "jroll_infinite_style";
			style.innerHTML = ".jroll-infinite-loading{-webkit-animation:jroll_infinite_loading 600ms linear infinite;animation:jroll_infinite_loading 600ms linear infinite}@-webkit-keyframes jroll_infinite_loading{from{-webkit-transform:rotateZ(0deg)}to{-webkit-transform:rotateZ(360deg)}}@keyframes jroll_infinite_loading{from{transform:rotateZ(0deg)}to{transform:rotateZ(360deg)}}";
			document.head.appendChild(style);
		}
	})(document);

	function JRoll_Infinite(wrap, options, jOptions) {

		var me = this;
		me.page = 1;
		me.id = null;
		me.refresh = false; //下拉刷新标记
		me.lock = false; //每次加载新页都会上锁，直到新页加载完成才开锁
		me.prefix = randomIdPrefix();
		me.direction = "+"; //滑动方向，默认向下，+表示向下 -表示向上
		me.options = {
			jroll:null,
			total: 10, //总页数
			limit: false, //限制最多只显示3页，默认不使用增减模式
			pullCss: "position:absolute;top:-42px;left:0;width:100%;height:42px;line-height:42px;text-align:center;display:block;",
			iconPull: "\u2193",
			iconUpdate: "\u21bb",
			iconFinish: "\u221a",
			iconCss: "display:inline-block;width:42px;",
			textPull: "下拉刷新",
			textRelease: "释放刷新",
			textUpdate: "正在加载",
			textFinish: "刷新完成",
			textCss: "",
			getData: null,  //获取数据的函数，必须返回一个数组，数组元素必须为对象
			template: "", //每条数据模板
			loadingTip: "<div class=\"jroll-infinite-tip\">正在加载...</div>",  //正在加载提示信息
			completeTip: "<div class=\"jroll-infinite-tip\">已加载全部内容</div>", //加载完成提示信息
			compile: compile, //编译方法
			render: render  //渲染方法
		};

		for (var i in options) {
			me.options[i] = options[i];
		}

		if (typeof jOptions !== "object") {
			jOptions = {
				bounce : true,
				scrollX: false
			};
		}

		me.compiled = me.options.compile(me.options.template);

		//用于清除提示信息
		var ltip = me.options.loadingTip.replace(/<img.+?\/>/, ".+?");
		var ctip = me.options.completeTip.replace(/<img.+?\/>/, ".+?");
		me.clearRegExp = new RegExp("("+ltip+"|"+ctip+")", "g");

		//创建JRoll
		me.jroll = (typeof me.options.jroll === "function") ? new me.options.jroll(wrap, jOptions) : new JRoll(wrap, jOptions);

		//如果scroller没有id，给其分配id
		if (!me.jroll.scroller.id) {
			me.jroll.scroller.id = me.prefix + "jroll";
		}
		me.id = me.jroll.scroller.id;

		me.jroll.on("scrollEnd", function() {
			if (!me.lock) {
				//上滑
				if (this.y > -1*qSr("#"+me.id+" .jroll-infinite-tip").offsetHeight && me.options.limit) {

					//如果有上一页，则加载上一页
					if (me.direction === "-") {
						if (me.page - 1 >= 1) {
							me.page = me.page - 1;
							me.getData();
						}
					} else {
						if (me.page - 3 >= 1) {
							me.page = me.page - 3;
							me.direction = "-";
							me.getData();
						}
					}
				}
				//下滑
				if (this.y < this.maxScrollY + qSr("#"+me.id+" .jroll-infinite-tip").offsetHeight) {

					//如果有下一页，则加载下一页
					if (me.direction === "+") {
						if (me.page + 1 <= me.options.total) {
							me.page = me.page + 1;
							me.getData();
						}
					} else {
						if (me.page + 3 <= me.options.total) {
							me.page = me.page + 3;
							me.direction = "+";
							me.getData();
						}
					}
				}
			}
		});

		//下拉刷新
		me.divPull = cDiv("div");
		me.divIcon = cDiv("span");
		me.divText = cDiv("span");

		me.setText(me.options.iconPull, me.options.textPull);

		me.divPull.style.cssText = me.options.pullCss;
		me.divIcon.style.cssText = me.options.iconCss;
		me.divText.style.cssText = me.options.textCss;
		me.divIcon.style[tSD] = "200ms";

		me.divPull.appendChild(me.divIcon);
		me.divPull.appendChild(me.divText);
		me.jroll.wrapper.appendChild(me.divPull);

		me.jroll.on("scroll", function() {
			me.divPull.style[tSF] = "translateY("+this.y+"px)";
			if (!me.lock) {
				if (this.y >= me.divPull.offsetHeight && gId(me.prefix+"page_1")) {
					if (!me.refresh) {
						me.refresh = true;
						me.divText.innerHTML = me.options.textRelease;
						me.divIcon.style[tSF] = "rotateZ(180deg)";
					}
				} else {
					if (me.refresh) {
						me.refresh = false;
						me.divText.innerHTML = me.options.textPull;
						me.divIcon.style[tSF] = "rotateZ(0deg)";
					}
				}
			}
		});

		me.jroll.scroller.addEventListener("touchend", function() {
			if (me.refresh && !me.lock) {
				me.jroll.options.momentum = false;
				me.jroll.options.bounce = false;
				me.jroll.scroller.style[tSD] = "200ms";
				me.jroll.scroller.style[tSF] = "translate(0px, " + me.divPull.offsetHeight + "px) translateZ(0) scale(" + me.jroll._zoom.scale + ")";
				me.divPull.style[tSD] = "200ms";
				me.divPull.style[tSF] = "translateY("+me.divPull.offsetHeight+"px)";
				setTimeout(function() {
					me.jroll.scroller.style[tSD] = "0ms";
					me.divPull.style[tSD] = "0ms";
				}, 200);
				me.setLoading();
				me.page = 1;
				me.getData();
			}
		}, false);

		//初始化
		me.init();
	}

	JRoll_Infinite.prototype = {
		init: function() {
			var me = this;
			me.getData();
		},
		setLoading: function() {
			var me = this;
			me.divIcon.className = "jroll-infinite-loading";
			setTimeout(function() { //30ms延迟用于解决低端安卓机icon重叠问题
				me.setText(me.options.iconUpdate, me.options.textUpdate);
			},30);
		},
		setText: function(a, b) {
			var me = this;
			me.divIcon.innerHTML = a;
			me.divText.innerHTML = b;
		},
		getData: function() {
			var me = this;
			me.lock = true;
			if (me.divPull.style.display === "block") {
				me.setLoading();
			}
			me.options.getData(me.page, me.callback.bind(me));
		},
		callback: function(data) {
			var me = this;
			var str, delChild, delHeight, html;

			me.lock = false;

			html = "<section id='"+me.prefix+"page_"+me.page+"'>";

			for (var i=0,l=data.length; i<l; i++) {
				html += me.options.render(me.compiled, data[i], i);
			}
			html += "</section>";

			me.divIcon.className = "";
			me.divIcon.style[tSF] = "rotateZ(360deg)";

			if (me.refresh) {
				me.direction = "+";
				me.jroll.options.momentum = true;
				me.jroll.options.bounce = true;
				me.jroll.scroller.innerHTML = "";
				me.setText(me.options.iconFinish, me.options.textFinish);
			} else {
				me.setText(me.options.iconPull, me.options.textPull);
			}

			if (me.direction === "-") {
				delChild = gId(me.prefix+"page_"+(me.page+3));
				delHeight = 1; //保证后面的判断成功
				me.jroll.scroller.removeChild(delChild);

				//不是第1页，顶部加上“正在加载”提示
				if (me.page !== 1) {
					str = me.options.loadingTip + html + me.jroll.scroller.innerHTML.replace(me.clearRegExp, "");
				} else {
					str =  html + me.jroll.scroller.innerHTML.replace(me.clearRegExp, "");
				}
			}

			if (me.direction === "+") {
				//大于第3页，顶部加上“正在加载”提示
				if (me.page - 3 > 0) {
					if (me.options.limit) { //使用增减模式
						delChild = gId(me.prefix+"page_"+(me.page-3));
						if (me.page === 4) {
							delHeight = delChild.offsetHeight - qSr("#"+me.id+" .jroll-infinite-tip").offsetHeight;
						} else {
							delHeight = delChild.offsetHeight;
						}
						me.jroll.scroller.removeChild(delChild);
						str = me.options.loadingTip + me.jroll.scroller.innerHTML.replace(me.clearRegExp, "") + html;
					} else {
						delHeight = 0;
						str = me.jroll.scroller.innerHTML.replace(me.clearRegExp, "") + html;
					}
				} else {
					str = me.jroll.scroller.innerHTML.replace(me.clearRegExp, "") + html;
				}
			}

			//不是最后一页，底部加上“正在加载”提示
			if (me.page !== me.options.total) {
				str += me.options.loadingTip;
			} else {
				str += me.options.completeTip;  //最后一页加“加载完成”提示
			}

			me.jroll.scroller.innerHTML = str;

			if (delHeight) {
				if (me.direction === "+") {
					me.jroll.scrollTo(0, me.jroll.y+delHeight);
				} else {
					if (me.page === 1) {
						delHeight = me.jroll.scroller.children[0].offsetHeight - qSr("#"+me.id+" .jroll-infinite-tip").offsetHeight;
					} else {
						delHeight = me.jroll.scroller.children[1].offsetHeight;
					}
					me.jroll.scrollTo(0, me.jroll.y - delHeight);
				}
			}
			me.jroll.refresh();

			if (gId(me.prefix+"page_1")) {
				me.divPull.style.display = "block";
			} else {
				me.divPull.style.display = "none";
			}

			if (me.refresh) {
				setTimeout(function() {
					me.jroll.scrollTo(0, 0, 400);
					me.divPull.style[tSD] = "400ms";
					me.divPull.style[tSF] = "translateY(0px)";
					setTimeout(function() {
						me.divPull.style[tSD] = "0ms";
						me.setText(me.options.iconPull, me.options.textPull);
					}, 400);
				}, 800);
				me.refresh = false;
			}
		}
	};

	if (typeof module !== 'undefined' && module.exports && !normalImport) {
		module.exports = JRoll_Infinite;
	} else if (typeof define === 'function' && !normalImport) {
		define(function() {return JRoll_Infinite;});
	} else {
		window.JRoll_Infinite = JRoll_Infinite;
	}

})(window, document);
